/*
 * macb.h
 *
 *  Created on: Aug 1, 2013
 *      Author: Ken Arok
 *
 * \brief Hardware Abstraction Layer of MACB Controller UC3C0512C
 *
 * Copyright (c) 2013 PT Hanindo Automation Solutions. All rights reserved.
 *
 */

#include "config_board.h"

#if BOARD_1_0_USED

#ifndef MACB_H_
#define MACB_H_

#ifdef __cplusplus
extern "C" {
#endif


/*! Packet structure.
 */
//! @{
typedef struct {
	unsigned char *data;
	unsigned int len;
} macb_packet_t;
//! @}

/*! Receive Transfer descriptor structure.
 */
//! @{
typedef struct  _AVR32_RxTdDescriptor {
	unsigned int addr;
	union
	{
		unsigned int status;
		struct {
			unsigned int BroadCast:1;
			unsigned int MultiCast:1;
			unsigned int UniCast:1;
			unsigned int ExternalAdd:1;
			unsigned int Res1:1;
			unsigned int Sa1Match:1;
			unsigned int Sa2Match:1;
			unsigned int Sa3Match:1;
			unsigned int Sa4Match:1;
			unsigned int TypeID:1;
			unsigned int VlanTag:1;
			unsigned int PriorityTag:1;
			unsigned int VlanPriority:3;
			unsigned int Cfi:1;
			unsigned int EndOfFrame:1;
			unsigned int StartOfFrame:1;
			unsigned int Rxbuf_off:2;
			unsigned int Res0:1;
			unsigned int Length:11;
		}S_Status;
	}U_Status;
}AVR32_RxTdDescriptor, *AVR32P_RxTdDescriptor;
//! @}

/*! Transmit Transfer descriptor structure.
 */
//! @{
typedef struct _AVR32_TxTdDescriptor {
	unsigned int addr;
	union
	{
		unsigned int status;
		struct {
			unsigned int BuffUsed:1;
			unsigned int Wrap:1;
			unsigned int TransmitError:1;
			unsigned int TransmitUnderrun:1;
			unsigned int BufExhausted:1;
			unsigned int Res1:10;
			unsigned int NoCrc:1;
			unsigned int LastBuff:1;
			unsigned int Res0:4;
			unsigned int Length:11;
		}S_Status;
	}U_Status;
}AVR32_TxTdDescriptor, *AVR32P_TxTdDescriptor;
//! @}

extern unsigned long MacbTxErrorCount; // Transmit error recovery counter

/*! Read a register on MDIO bus (access to the PHY)
 *         This function is looping until PHY gets ready
 *
 * \param macb         Input. instance of the MACB to use
 * \param usAddress    Input. register to set.
 *
 * \return unsigned long data that has been read
 */
extern unsigned long ulReadMDIO(volatile avr32_macb_t *macb, unsigned short usAddress);

/*! Write a given value to a register on MDIO bus (access to the PHY)
 *         This function is looping until PHY gets ready
 *
 * \param *macb        Input. instance of the MACB to use
 * \param usAddress    Input. register to set.
 * \param usValue      Input. value to write.
 *
 */
extern void vWriteMDIO(volatile avr32_macb_t *macb, unsigned short usAddress, unsigned short usValue);

/**
 * \brief initialize the MACB driver.
 *
 * \param *macb Base address of the MACB
 *
 * \return true if success, false otherwise.
 */
extern bool xMACBInit(volatile avr32_macb_t *macb);

/**
 * \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
 * MACB Tx buffers, then indicates to the MACB that the buffer is ready.
 * If lEndOfFrame is true then the data being copied is the end of the frame
 * and the frame can be transmitted.
 *
 * \param *macb        Base address of the MACB
 * \param *pvFrom      Address of the data buffer
 * \param ulLength     Length of the frame
 * \param lEndOfFrame  Flag for End Of Frame
 *
 * \return length sent.
 */
extern unsigned long lMACBSend(volatile avr32_macb_t *macb, const void *pvFrom, unsigned long ulLength, long lEndOfFrame);

/**
 * \brief Frames can be read from the MACB in multiple sections.
 * Read ulSectionLength bytes from the MACB receive buffers to pcTo.
 * ulTotalFrameLength is the size of the entire frame.  Generally vMACBRead
 * will be repetedly called until the sum of all the ulSectionLenths totals
 * the value of ulTotalFrameLength.
 *
 * \param *pvTo               Address of the buffer
 * \param ulSectionLength     Length of the buffer
 * \param ulTotalFrameLength  Length of the frame
 */
extern void vMACBRead(void *pvTo, unsigned long ulSectionLength, unsigned long ulTotalFrameLength);

/**
 * \brief Called by the Tx interrupt, this function traverses the buffers used to
 * hold the frame that has just completed transmission and marks each as
 * free again.
 */
extern void vClearMACBTxBuffer(void);

/**
 * \brief Called by the Tx error interrupt, this function marks ALL buffers as
 * free again.
 */
extern void vClearMACBTxBuffersAfterTxError(void);

/**
 * \brief Wait for new Ethernet data.
 *
 * - FreeRTOS implementation: Suspend on a semaphore waiting either for the
 * semaphore to be obtained or a timeout. The semaphore is used by the MACB ISR
 * to indicate that data has been received and is ready for processing.
 *
 * - Stand-alone implementation: Check, until timeout, a local variable updated
 * by the MACB ISR upon data reception.
 *
 * \param ulTimeOut    time to wait for an input
 *
 * \return true if success, false otherwise.
 */
extern bool vMACBWaitForInput(unsigned long ulTimeOut);
/**
 * \brief Function to get length of the next frame in the receive buffers
 *
 * \return the length of the next frame in the receive buffers.
 */
extern unsigned long ulMACBInputLength(void);

/**
 * \brief Set the MACB Physical address (SA1B & SA1T registers).
 *
 * \param *MACAddress the MAC address to set.
 */
extern void vMACBSetMACAddress(const unsigned char *MACAddress);

/**
 * \brief Disable MACB operations (Tx and Rx).
 *
 * \param *macb        Base address of the MACB
 */
extern void vDisableMACBOperations(volatile avr32_macb_t *macb);

/**
 * \brief Check status of network link connection.
 *
 * \param *macb        Base address of the MACB
 *
 * \return true if link is connected. Unless false.
 *
 */
extern bool vMACBNetworkIsConnected(volatile avr32_macb_t *macb);

#ifdef __cplusplus
}
#endif

#endif /* MACB_H_ */

#endif /* BOARD_1_0_USED */
